package com.danco.training.zaneuskaya.connection.dao.impl;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.danco.training.zaneuskaya.connection.dao.AbstractHibernateDao;
import com.danco.training.zaneuskaya.connection.dao.OrderDao;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.domain.Order;


public class OrderDaoImpl extends AbstractHibernateDao<Order, Integer> implements
		OrderDao {

	
	

	@Override
	public List<Order> readExecutedOrders(Session session) {
		Criteria criteria = session.createCriteria(Order.class);
		
	
		criteria.add(Restrictions.eq("executed", true));
		
		return criteria.list();
	}

	@Override
	public List<Order> readNotExecutedOrders(Session session) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Restrictions.eq("executed", false));
		return criteria.list();
	}

	@Override
	public List<Order> readExecutedOrdersForPeriod(Session session ,
			Date from, Date to) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Restrictions.eq("executed", true));
		criteria.add(Restrictions.between("orderDate", from,to));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return criteria.list();
	}

	@Override
	public List<Order> readOrdersSortedByOrderDate(Session session) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.addOrder(org.hibernate.criterion.Order.asc("orderDate"));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return criteria.list();
	}

	@Override
	public List<Order> readOrdersSortedByTotalPrice(Session session) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.addOrder(org.hibernate.criterion.Order.asc("totalPrice"));
		
		return criteria.list();
	}

	@Override
	public List<Order> readOrdersSortedByOrderState(Session session) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.addOrder(org.hibernate.criterion.Order.asc("executed"));
		return criteria.list();
	}

	@Override
	public List<Order> readExecutedOrdersSortedByOrderDate(
			Session session, Date from, Date to) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Restrictions.eq("executed", true));
		criteria.add(Restrictions.between("orderDate", from,to));
		criteria.addOrder(org.hibernate.criterion.Order.asc("orderDate"));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return criteria.list();
	}

	@Override
	public List<Order> readExecutedOrdersSortedByPrice(Session session,
			Date from, Date to) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Restrictions.eq("executed", true));
		criteria.add(Restrictions.between("orderDate", from,to));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.addOrder(org.hibernate.criterion.Order.asc("totalPrice"));
		return criteria.list();
	}

	@Override
	public boolean addBookOrder(Session session, Order order, Book book) {		
	
			order.getBooks().add(book);
			update(session, order);
			return true;
		
		
	}

	@Override
	public boolean removeBookOrder(Session session, Order order, Book book) {
		
		List<Book> books = order.getBooks();
		books.remove(book);
			order.setBooks(books);
			update(session, order);
			return true;
		
	}

	@Override
	public boolean executeOrder(Session session, Integer id) {
	   
			Order order = read(session, id);
			order.setExecuted(false);
			update(session, order);
			return true;
		
	}

	@Override
	public List<Order> findOrderByBook(Session session, Book book) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.createAlias("books", "b");
		criteria.add(Restrictions.eq("b.bookId",book.getBookId()));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return criteria.list();
	}

	@Override
	public boolean deleteOrderByBookFromOrderBook(Session session,
			Book book) {
		for (Order order: findOrderByBook(session, book)){
			
				delete(session, order);
			
		}
		return true;
	}

	@Override
	public List<Book> findBooksByOrderId(Session session, Integer id) {
	
		
			Order order = read(session, id);
			return order.getBooks();
		
		
		
		
	}
	
	@Override
	public Order read(Session session, Integer PK)
			throws HibernateException {
		
		return (Order) super.read(session, Order.class, PK);
	}

	@Override
	public List<Order> readAll(Session session) throws HibernateException {
		
		return super.readAll(Order.class, session);
	}


	

}
